﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
/// <summary>
/// 可视DEBUG
/// </summary>
public class VisualLog4U3D : MonoBehaviour
{
    #region XXX
    class StrPare
    {
        public string Str1;
        public string Str2;

        public StrPare(string s1, string s2)
        {
            Str1 = s1;
            Str2 = s2;
        }
    }

    static List<StrPare> lst_log = new List<StrPare>();
    static List<StrPare> lst_warming = new List<StrPare>();
    static List<StrPare> lst_error = new List<StrPare>();

    private bool show = false;
    public bool showLog = true, showWarning = true, showError = true, autoSave = false;
    public int MaxLine = 100;

    void Awake()
    {
        if (MaxLine > 999)
            MaxLine = 999;
        SetWHByScale(1, 1);
        Application.logMessageReceived+=HandleLog;
        curLst = lst_log;
    }
    //系统debug回调
    void HandleLog(string logString, string stackTrace, LogType type)
    {
        List<StrPare> tlst = lst_error;
        switch (type)
        {
            case LogType.Log:
                tlst = lst_log;
                break;
            case LogType.Warning:
                tlst = lst_warming;
                break;
        }
        addList<StrPare>(tlst, new StrPare(logString, stackTrace), 100);
    }
    int index = 0;
    int lastIndex = 0;
    Rect rootRect;
    List<StrPare> curLst;
    void OnGUI()
    {
        if (!show)
        {
            //GUILayout.FlexibleSpace();
            //if (GUILayout.Button("show", GUILayout.Width(Screen.width / 5), GUILayout.Height(Screen.height / 20)))
            //{
            //    SwitchLog(true);
            //}
            return;
        }
        else
            rootRect = GUI.Window(0, rootRect, rootWinFunc, new GUIContent("VisualLog4U3D"));


    }
    int w = 0;
    int h = 0;
    void rootWinFunc(int id)
    {
        GUI.BeginGroup(new Rect(10, 20, rootW - 10 * 2, rootH - 20 * 2));
        if (w == 0)
            w = rootW - 10 * 2;
        if (h == 0)
            h = rootH - 20 * 2;
        index = GUI.Toolbar(new Rect(0, 0, w - h / 5f, h / 10f), index, new string[] { "log_" + lst_log.Count, "warning_" + lst_warming.Count, "error_" + lst_error.Count });
        if (lastIndex != index)
        {
            traceStr = "";
            lastIndex = index;
            switch (index)
            {
                case 0:
                    curLst = lst_log;
                    break;
                case 1:
                    curLst = lst_warming;
                    break;
                case 2:
                    curLst = lst_error;
                    break;
            }
        }
        if (GUI.Button(new Rect(w - h / 5f, 0, h / 10f, h / 10f), "C"))
        {
            curLst.Clear();
            traceStr = "";
        }
        if (GUI.Button(new Rect(w - h / 5f + h / 10f, 0, h / 10f, h / 10f), "X"))
        {
            SwitchLog(false);
        }
        //Log
        GUI.BeginGroup(new Rect(0, h / 10f + 10, w, h / 2 - 10));
        logWinFunc(2, w, h);
        GUI.EndGroup();
        //Trace
        GUI.BeginGroup(new Rect(0, h / 10f * 6, w, h / 10f * 4));
        traceWinFunc(3, w, h);
        GUI.EndGroup();

        GUI.EndGroup();

        //GUI.DragWindow(new Rect(0, 0, Screen.width - 10, Screen.height - 10));
    }
    Vector2 scrollPos2 = Vector2.zero;
    void logWinFunc(int id, int w, int h)
    {
        scrollPos2 = GUI.BeginScrollView(new Rect(0, 0, w, h / 2), scrollPos2, new Rect(0, 0, w, h / 20 * curLst.Count));
        for (int i = 0; i < curLst.Count; i++)
        {
            if (GUI.Button(new Rect(0, 0 + i * h / 20f, w - 20, h / 20f), i.ToString() + " " + curLst[i].Str1))
            {
                traceStr = curLst[i].Str1 + "\n" + curLst[i].Str2;
            }
        }
        GUI.EndScrollView();
    }
    string traceStr = "";
    Vector2 scrollPos = Vector2.zero;
    void traceWinFunc(int id, int w, int h)
    {
        scrollPos = GUI.BeginScrollView(new Rect(0, 0, w, h / 10f * 4), scrollPos, new Rect(0, 0, w, h));
        GUI.Box(new Rect(0, 0, w - 20, h), traceStr);
        GUI.EndScrollView();
    }
    static void addList<T>(List<T> lst, T val, int maxCount)
    {
        while (lst.Count >= maxCount)
        {
            lst.RemoveAt(0);
        }
        lst.Add(val);
    }
    #endregion
    static int rootW, rootH;
    public static VisualLog4U3D Get()
    {
        var inst = GameObject.FindObjectOfType<VisualLog4U3D>();
        if (inst == null)
        {
            GameObject visualLog = new GameObject("VisualLog4U3D");
            inst = visualLog.AddComponent<VisualLog4U3D>();
        }
        return inst;
    }
    public void SwitchLog(bool on_off)
    {
        this.show = on_off;
    }
    public void SetWHByScale(float sx, float sy)
    {
        rootW = (int)(Screen.width * sx);
        rootH = (int)(Screen.height * sy);
        rootRect = new Rect(0, 0, rootW, rootH);
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
            this.show = !this.show;
    }
}
